package net.jlibrary.common.project.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import freemarker.template.utility.XmlEscape;
import net.jlibrary.common.CoreConstants;
import net.jlibrary.common.project.interceptor.ExecutionTimeInterceptor;
import net.jlibrary.common.project.interceptor.PurviewInterceptor;
import net.jlibrary.common.project.interceptor.TokenInterceptor;
import net.jlibrary.common.tools.FreemarkerStaticModels;

@Configuration
// @PropertySource("classpath:/datasource.properties")
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "net.jlibrary.**.action", "net.jlibrary.common.exception",
		"net.jlibrary.common.conversion"}, includeFilters = { @Filter(value = { RestController.class,
		ControllerAdvice.class }) })
public class SpringMvcConfig extends WebMvcConfigurerAdapter {
	@Resource
	private Environment env;

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
		configurer.enable();
	}

	@Override
	public Validator getValidator() {
		LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
		validator.setProviderClass(HibernateValidator.class);
		validator.setValidationMessageSource(messageSource());
		return validator;
	}

	/**
	 * 加入拦截器
	 */
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(tokenInterceptor()).addPathPatterns("/**").excludePathPatterns("/cameraWireless/**");
		registry.addInterceptor(executionTimeInterceptor()).addPathPatterns("/**").excludePathPatterns("/cameraWireless/**");
		//registry.addInterceptor(purviewInterceptor()).addPathPatterns("/**").excludePathPatterns("/cameraWireless/**");

	}

	@Bean
	public TokenInterceptor tokenInterceptor() {
		TokenInterceptor tokenInterceptor = new TokenInterceptor();
		return tokenInterceptor;
	}
	
	@Bean
	public ExecutionTimeInterceptor executionTimeInterceptor() {
		ExecutionTimeInterceptor executionTimeInterceptor = new ExecutionTimeInterceptor();
		return executionTimeInterceptor;
	}
	
	@Bean
	public PurviewInterceptor purviewInterceptor() {
		PurviewInterceptor purviewInterceptor = new PurviewInterceptor();
		return purviewInterceptor;
	}
	
//	@Bean
//	public CurbParkingRecordInterceptor curbParkingRecordInterceptor() {
//		CurbParkingRecordInterceptor curbParkingRecordInterceptor = new CurbParkingRecordInterceptor();
//		return curbParkingRecordInterceptor;
//	}

	@Bean
	public ReloadableResourceBundleMessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setBasenames("classpath:message-info", "classpath:message-exception",
				"classpath:message-validator", "classpath:org/hibernate/validator/ValidationMessages");
		messageSource.setUseCodeAsDefaultMessage(false);
		messageSource.setDefaultEncoding(CoreConstants.CORE_ENCODING);
		// messageSource.setCacheSeconds(-1);
		return messageSource;
	}

	@SuppressWarnings("unchecked")
	@Bean
	public FreeMarkerViewResolver viewResolver() {
		FreeMarkerViewResolver fm = new FreeMarkerViewResolver();
		fm.setViewClass(FreeMarkerView.class);
		fm.setContentType("text/html; charset=" + CoreConstants.CORE_ENCODING);
		fm.setCache(true);
		fm.setPrefix("");
		fm.setSuffix(".ftl");
		fm.setOrder(1);
		fm.setRequestContextAttribute("rc");
		fm.setRedirectHttp10Compatible(false);
		fm.setAttributesMap(freemarkerStaticModels());
		return fm;
	}

	@Bean
	public FreeMarkerConfigurer freeMarkerConfigurer() {
		FreeMarkerConfigurer fc = new FreeMarkerConfigurer();
		fc.setTemplateLoaderPath("/");
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("xml_escape", fmXmlEscape());
		fc.setFreemarkerVariables(variables);
		Properties props = new Properties();
		props.setProperty("default_encoding", CoreConstants.CORE_ENCODING);
		props.setProperty("number_format", "0.##");
		props.setProperty("date_format", "yyyy-MM-dd");
		props.setProperty("time_format", "HH:mm:ss");
		props.setProperty("datetime_format", "yyyy-MM-dd HH:mm");
		props.setProperty("auto_import", "/misc/spring.ftl as i18n");
		// props.setProperty("template_exception_handler", "ignore");
		// props.setProperty("template_update_delay", "60000");
		fc.setFreemarkerSettings(props);
		return fc;
	}

	@Bean
	public XmlEscape fmXmlEscape() {
		XmlEscape xe = new XmlEscape();
		return xe;
	}

	@Bean
	public FreemarkerStaticModels freemarkerStaticModels() {
		FreemarkerStaticModels freemarkerStaticModels = FreemarkerStaticModels.getInstance();
		Properties props = new Properties();
		// 加入可以在freemarker使用的静态方法
		props.put("StringUtil", "net.jlibrary.common.tools.StringUtil");
		props.put("DateUtil", "net.jlibrary.common.tools.DateUtil");
		props.put("NumberUtil", "net.jlibrary.common.tools.NumberUtil");
		props.put("CoreConstants", "net.jlibrary.common.CoreConstants");
		props.put("MessageMap", "net.jlibrary.vo.MessageMap");
		props.put("VehicularTrafficVo", "net.jlibrary.vo.pc.VehicularTrafficVo");
		props.put("VehicleParkGatewayVo", "net.jlibrary.vo.pc.VehicleParkGatewayVo");
		freemarkerStaticModels.setStaticModels(props);
		return freemarkerStaticModels;
	}

	@Bean
	public CommonsMultipartResolver multipartResolver() {
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setMaxUploadSize(env.getProperty("upload.attach.size", Long.class));
		return multipartResolver;
	}
	
//	@Bean  
//	public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {  
//	    SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();  
//	    resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);  
//	    Properties mappings = new Properties();  
//	    //key是异常类型,value是返回的视图名称  
//	    mappings.setProperty(NoHandlerFoundException.class.getName(), "error/404");
//	    resolver.setExceptionMappings(mappings);// None by default  
//	    resolver.setDefaultErrorView("error/500");// No default  
//	    resolver.setExceptionAttribute("exception"); // Default is "exception"  
//	    resolver.setWarnLogCategory(getClass().getName()); // No default  
//	    return resolver;  
//	} 

//	@Bean
//	public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
//		MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
//		List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
//		MediaType mediaType = new MediaType("text/html");
//		supportedMediaTypes.add(mediaType);
//		mappingJackson2HttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
//		RequestMappingHandlerAdapter a;
//		return mappingJackson2HttpMessageConverter;
//	}
}
